package org.xtframe.bean;

import java.util.List;
import java.util.Map;

import org.xtframe.common.CollectionsUtil;
import org.xtframe.common.json.JSON2Java;
import org.xtframe.dao.DataBaseDao;
import org.xtframe.dao.DataBaseFactory;
import org.xtframe.entity.ServerData;
import org.xtframe.entity.UserData;
import org.xtframe.service.AjaxDataHandlerException;
import org.xtframe.service.impl.BasicExecute;
import org.xtframe.util.ContextUtil;
import org.xtframe.vo.CheckVO;

/**
 * Bean类 - 分页
 * 
 * @author SunYong
 */

public class Pager extends BasicExecute {

	public static final Integer MAX_PAGE_SIZE = 500;// 每页最大记录数限制
	public static final String pageNumberName = "_s";// 当前页码名称
	public static final String pageSizeName = "_l";// 每页记录数名称

	private String name = "";// 控件名称
	
	private String totalSql;// 查询记录总数
	private String querySql;// 查询分页数据
	
	private Integer pageNumber = 1;// 当前页码
	private Integer pageSize = 20;// 每页记录数
	private Integer totalCount = 0;// 总记录数
	private Integer pageCount = 0;// 总页数
	private Map<String, Object> property;//数据参数
	private List<?> list;// 数据List
	
	public Pager(String totalSql, String querySql, Map<String, Object> property){
		this("", totalSql, querySql, property);
	}
	
	public Pager(String name, String totalSql, String querySql, Map<String, Object> property){
		this.name = name;
		this.totalSql = totalSql;
		this.querySql = querySql;
		this.property = property;
		setPageNumber(JSON2Java.optInteger(property.get(getPagenumbername()), 1));
		setPageSize(JSON2Java.optInteger(property.get(getPagesizename()), 20));
		
		property.put(getPagenumbername(), (getPageNumber()-1)*getPageSize());
		property.put(getPagesizename(), getPageSize());
	}
	
	@SuppressWarnings("unchecked")
	public boolean execute() {
		try {
			UserData userData = ContextUtil.getCurrentUserData();
			ServerData serverData = ContextUtil.getServerData();
			
			Map<String, Object> parameter = (Map<String, Object>)CollectionsUtil.clone(property);
			CheckVO checkVO = check(totalSql, parameter, userData, serverData);
			switch(checkVO.getResult()){
				case CheckVO.SQLID_NULL:
					throw new AjaxDataHandlerException("sqlID为空");
				case CheckVO.SQLID_NO_RIGHT:
					throw new AjaxDataHandlerException("不具有该sql("+totalSql+")的执行权限");
				case CheckVO.SQLID_INEXISTENCE:
					throw new AjaxDataHandlerException("该sql("+totalSql+")不存在");
				case CheckVO.CHECK_FAILED:
					throw new AjaxDataHandlerException("sql("+totalSql+")数据格式校验失败");
				case CheckVO.LOGIN_AGAIN:
					throw new AjaxDataHandlerException("需要进行登录");
			}
			DataBaseDao dataBaseDao = DataBaseFactory.getDataBaseDaoForSqlId(totalSql);
			totalCount = dataBaseDao.findRows(checkVO.getSqlData().getSql());
			
			parameter = (Map<String, Object>)CollectionsUtil.clone(property);
			checkVO = check(querySql, parameter, userData, serverData);
			switch(checkVO.getResult()){
				case CheckVO.SQLID_NULL:
					throw new AjaxDataHandlerException("sqlID为空");
				case CheckVO.SQLID_NO_RIGHT:
					throw new AjaxDataHandlerException("不具有该sql("+querySql+")的执行权限");
				case CheckVO.SQLID_INEXISTENCE:
					throw new AjaxDataHandlerException("该sql("+querySql+")不存在");
				case CheckVO.CHECK_FAILED:
					throw new AjaxDataHandlerException("sql("+querySql+")数据格式校验失败");
				case CheckVO.LOGIN_AGAIN:
					throw new AjaxDataHandlerException("需要进行登录");
			}
			list = dataBaseDao.executeQuery(checkVO.getSqlData().getSql(), checkVO.getSqlData().getPreparedParameters());
			
			return true;
		} catch (Exception e) {
			list = null;
			totalCount = 0;
			e.printStackTrace();
		}
		return false;
	}

	public Integer getPageNumber() {
		return pageNumber;
	}

	public void setPageNumber(Integer pageNumber) {
		if (pageNumber < 1) {
			pageNumber = 1;
		}
		this.pageNumber = pageNumber;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		if (pageSize < 1) {
			pageSize = 1;
		} else if (pageSize > MAX_PAGE_SIZE) {
			pageSize = MAX_PAGE_SIZE;
		}
		this.pageSize = pageSize;
	}

	public Integer getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(Integer totalCount) {
		this.totalCount = totalCount;
	}

	public Integer getPageCount() {
		pageCount = totalCount / pageSize;
		if (totalCount % pageSize > 0) {
			pageCount++;
		}
		return pageCount;
	}

	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}

	public List<?> getList() {
		return list;
	}

	public void setList(List<?> list) {
		this.list = list;
	}

	public Map<String, Object> getProperty() {
		return property;
	}

	public void setProperty(Map<String, Object> property) {
		this.property = property;
	}

	public String getTotalSql() {
		return totalSql;
	}

	public void setTotalSql(String totalSql) {
		this.totalSql = totalSql;
	}

	public String getQuerySql() {
		return querySql;
	}

	public void setQuerySql(String querySql) {
		this.querySql = querySql;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPagenumbername() {
		return name + pageNumberName;
	}

	public String getPagesizename() {
		return name + pageSizeName;
	}
	
	public String getUrlParameter() {
		StringBuffer ret = new StringBuffer();
		boolean flag = true;
		for (Map.Entry<String, Object> entry : property.entrySet()) {
			String key = entry.getKey().toString();
			String value = entry.getValue().toString();
			if(key.equals(getPagenumbername()) || key.equals(getPagesizename())) continue;
			if(flag) {
				ret.append(key).append("=").append(value);
				flag = false;
			} else {
				ret.append("&").append(key).append("=").append(value);
			}
		}
		return ret.toString();
	}

}